using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Betalgo.Ranul.OpenAI;
using Betalgo.Ranul.OpenAI.Managers;
using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels;
using HengTong.Model.Db.Ai;
using HengTong.Model.Db.SupplyChain.Material;
using HengTong.Model.Gpt;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TiaoTaoHelper.Extension.String;
using TiaoTaoHelper.Models;
using UUIDNext;

namespace HengTong.ViewModel.SupplyChain.SysMaterialAttributeVms
{
    public partial class SysMaterialAttributeListVm
    {
        private ILogger<SysMaterialAttributeListVm> Logger { get; set; }
        
        public async Task AiGenerateNonKeyAttributes(Guid materialId)
        {
            var scope = Wtm.ServiceProvider.CreateScope();
            Logger = scope.ServiceProvider.GetRequiredService<ILogger<SysMaterialAttributeListVm>>();
            var prompt = await DC.Set<SysPrompt>()
                .AsNoTracking()
                .Where(e => e.Name == "物料生成采购属性" && e.IsEnabled == true)
                .FirstOrDefaultAsync();
            if (prompt == null)
            {
                MSD.AddModelError(" ", "未找到对应的AI提示语，请联系管理员配置");
                return;
            }

            var material = await DC.Set<SysMaterial>()
                .AsNoTracking()
                .Include(e => e.MaterialGroup)
                .Include(e => e.Attributes)
                .ThenInclude(e => e.Values)
                .FirstOrDefaultAsync(e => e.ID == materialId);
            if (material == null)
            {
                MSD.AddModelError(" ", "未找到对应的物料信息");
                return;
            }
            var data = await AiClearData(material, prompt);
            if (data.Any())
            {
                foreach (var attr in data)
                {
                    if (material.Attributes.Any(a => a.Name == attr.Name))
                    {
                        continue;
                    }
                    var newAttr = new SysMaterialAttribute
                    {
                        ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                        MaterialId = material.ID,
                        Name = attr.Name,
                        IsKeyAttribute = false,
                        Remark = "AI生成",
                        Order = material.Attributes.Where(a => a.IsKeyAttribute == false).Select(a => a.Order).DefaultIfEmpty(0).Max() + 1,
                        Values = attr.Values.Select(e => e.Trim()).Distinct().Select(v => new SysMaterialAttributeValue
                        {
                            ID = Uuid.NewDatabaseFriendly(Database.SqlServer),
                            Value = v
                        }).ToList()
                    };
                    DC.Set<SysMaterialAttribute>().Add(newAttr);
                    material.Attributes.Add(newAttr);
                }
                await DC.SaveChangesAsync();
            }
        }
        
        
            private async Task<GptMaterialAttribute[]> AiClearData(SysMaterial material, SysPrompt prompt)
            {
                try
                {
                    var info = $"物料名称: {material.Name}\n物料分组:{material.MaterialGroup?.Name}\n{string.Join(", ", material.Attributes.Where(a => a.IsKeyAttribute).Select(a => a.Name + ": " + string.Join("/", a.Values.Select(v => v.Value))))}";
                    var user = prompt.UserPrompt.Replace("@物料信息@", info);
                    var system = prompt.SystemPrompt;
                    // 初始请求
                    var response = await GptChatWithContinue(system, user);
                    if (response.Code == 200)
                    {
                        var fullContent = response.Data;
                        
                        // 尝试解析完整的JSON
                        if(!fullContent.TryJsonParse(out List<GptMaterialAttribute> result, out var error))
                        {
                            Logger.LogError(error, "整理物料采购属性失败: 返回结果无法解析为属性列表, 返回内容: {content}", fullContent);
                            MSD.AddModelError(" ", "整理物料采购属性失败: 返回结果无法解析为属性列表");
                            return null;
                        }
                        return result.ToArray();
                    }
                    else
                    {
                        Logger.LogError("整理物料采购属性失败: {message}", response.Message);
                        MSD.AddModelError(" ", $"整理物料采购属性失败: {response.Message}");
                        return null;
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "整理物料采购属性失败: {message}", e.Message);
                    MSD.AddModelError(" ", $"整理物料采购属性失败: {e.Message}");
                    return null;
                }
            }
            
            /// <summary>
            /// 支持continue机制的GPT聊天，自动处理不完整的JSON响应
            /// </summary>
            private async Task<Result<string>> GptChatWithContinue(string system, string user)
            {
                const int maxContinueAttempts = 5; // 最多continue 3次
                var messageHistory = new List<ChatMessage>
                {
                    ChatMessage.FromSystem(system),
                    ChatMessage.FromUser(user)
                };
                
                string combinedContent = "";
                int continueCount = 0;
                
                while (continueCount <= maxContinueAttempts)
                {
                    var chatResult = await GptChat(messageHistory);
                    
                    if (chatResult.Code != 200)
                    {
                        return new Result<string>(chatResult.Message);
                    }
                    
                    var currentContent = chatResult.Data.Last().Content;
                    
                    if (string.IsNullOrEmpty(currentContent))
                    {
                        Logger.LogWarning("AI返回内容为空");
                        return new Result<string>("AI返回内容为空");
                    }
                    
                    // 累积内容
                    if (continueCount == 0)
                    {
                        combinedContent = currentContent;
                    }
                    else
                    {
                        // continue的内容直接拼接（移除可能重复的开头字符）
                        combinedContent += currentContent.TrimStart();
                    }
                    
                    // 检查JSON是否完整有效
                    if (IsValidJson(combinedContent))
                    {
                        Logger.LogInformation("JSON数据完整有效，共进行了 {count} 次continue", continueCount);
                        return new Result<string>
                        {
                            Data = combinedContent
                        };
                    }
                    
                    // JSON不完整，尝试continue
                    if (continueCount < maxContinueAttempts)
                    {
                        Logger.LogInformation("JSON数据不完整，发送第 {count} 次continue请求", continueCount + 1);
                        
                        // 将AI的响应加入历史
                        messageHistory.Add(ChatMessage.FromAssistant(currentContent));
                        
                        // 发送continue消息
                        messageHistory.Add(ChatMessage.FromUser("continue"));
                        
                        continueCount++;
                        await Task.Delay(500); // 短暂延迟
                    }
                    else
                    {
                        // 达到最大continue次数，返回错误
                        Logger.LogError("已达到最大continue次数 {max}，JSON数据仍然不完整: {@content}", maxContinueAttempts, combinedContent);
                        return new Result<string>("JSON数据不完整，已达到最大continue次数");
                    }
                }
                
                return new Result<string>("未知错误");
            }
            
            /// <summary>
            /// 使用 System.Text.Json 检查 JSON 是否完整且有效
            /// </summary>
            /// <param name="json">JSON字符串</param>
            /// <returns>是否为完整有效的JSON</returns>
            private bool IsValidJson(string json)
            {
                if (string.IsNullOrWhiteSpace(json))
                {
                    return false;
                }
                
                try
                {
                    // 使用 JsonDocument 验证 JSON 是否完整有效
                    using var document = JsonDocument.Parse(json);
                    // 如果能成功解析，说明 JSON 完整有效
                    return true;
                }
                catch (JsonException ex)
                {
                    // JSON 格式错误或不完整
                    Logger.LogWarning("JSON数据无效: {message}", ex.Message);
                    return false;
                }
            }
            
            /// <summary>
            /// GPT对话，支持传入完整的消息历史（用于continue机制）
            /// </summary>
            private async Task<Result<List<ChatMessage>>> GptChat(List<ChatMessage> messages, int? maxTokens = null)
            {
                var httpClient = new HttpClient();
                httpClient.Timeout = TimeSpan.FromMinutes(10);
                var openAiService = new OpenAIService(new OpenAIOptions()
                {
                    ApiKey = "sk-d0b536968d5d46b0b8e8fa60dd8c1f6d",
                    BaseDomain = "https://api.deepseek.com/v1"
                }, httpClient);
                
                var chatRequest = new ChatCompletionCreateRequest
                {
                    Messages = messages,
                    Model = "deepseek-chat",
                    MaxTokens = maxTokens ?? 8192,
                    ResponseFormat = new ResponseFormat{
                        Type = "json_object"
                    }
                };
                var completionResult = await openAiService.ChatCompletion.CreateCompletion(chatRequest);
                if (completionResult.Successful)
                {
                    var response = completionResult.Choices.First().Message.Content;
                    if (!string.IsNullOrWhiteSpace(response))
                    {
                        messages.Add(ChatMessage.FromAssistant(response));
                        return new Result<List<ChatMessage>>()
                        {
                            Data = messages
                        };
                    }
                    else
                    {
                        return new Result<List<ChatMessage>>("返回内容为空");
                    }
                }
                else
                {
                    return new Result<List<ChatMessage>>(completionResult.Error?.Message ?? "未知错误");
                }
            }
    }
}
